#include "auth.h"
#include <stdio.h>
#include <unistd.h>
#include "../utils/cJSON.h"
#include "../utils/log.h"
#include <stdbool.h>

#define USER_DB_PATH "./db/user"

user_db *db;

static unsigned long id_increment = 1;

// 初始化用户数据库
void load_user_db() {
    db = (user_db*)malloc(sizeof(user_db));
    INIT_LIST_HEAD(&db->user_list.list);
    db->user_count = 0;
    db->map = NULL;
    log_debug("db init %s", USER_DB_PATH);
    
    FILE* file = fopen(USER_DB_PATH, "r");
    if (file == NULL) {
        perror("no such file");
        return;
    }
    log_info("load user db");
    // 格式为 username password, 逐行读取
    while (!feof(file)){
        user_info* user = malloc(sizeof(user_info));
        user_map* entry = malloc(sizeof(user_map));
        user_node_t *node = malloc(sizeof(user_node_t));
        fscanf(file, "%d %s %s",&user->id, user->username, user->password);
        
        user->id = id_increment++;
        node->user = user;
        entry->node = node;
        entry->username = user->username;
        HASH_ADD_KEYPTR(hh, db->map, user->username, strlen(user->username), entry);
        list_add_tail(&node->list, &db->user_list.list);
        db->user_count++;
        log_debug("user load: username:%s password:%s", user->username, user->password);
    }
    fclose(file);
    return db;
}

// 添加用户
int add_user(const char* username, const char* password) {
    // 检查用户名是否已存在
    user_map* entry = NULL;
    HASH_FIND_STR(db->map, username, entry);
    if (entry != NULL) {
        return -1; // 用户名已存在
    }
    // 创建新用户
    user_info* user = malloc(sizeof(user_info));
    entry = malloc(sizeof(user_map));
    strcpy(user->username, username);
    strcpy(user->password, password);
    user->id = id_increment++;

    user_node_t *node = malloc(sizeof(user_node_t));
    node->user = user;

    entry->username = user->username;
    entry->node = node;
    HASH_ADD_KEYPTR(hh, db->map, user->username, strlen(user->username), entry);
    list_add_tail(&node->list, &db->user_list.list);
    db->user_count++;
    // 保存到文件
    FILE* file = fopen(USER_DB_PATH, "a");
    fprintf(file, "%d %s %s\n", user->id, username, password);
    fclose(file);
    return user->id; // 添加成功, 返回id
}

// 获取用户信息
user_info* get_user(const char* username) {
    user_map* entry = NULL;
    HASH_FIND_STR(db->map, username, entry);
    if (entry == NULL) {
        return NULL; // 用户名不存在
    }
    return entry->node->user;
}

// 验证用户
user_info* verify_user(const char* username, const char* password) {
    user_info* user = get_user(username);
    if (user == NULL) {
        return NULL; // 用户名不存在
    }
    if (strcmp(user->password, password) == 0) {
        return user; // 验证成功
    }
    return NULL;
}

/**
 * @brief 注册账号
 * request:{
 *     "username": "string",
 *     "password": "string"
 * }
 * response:{
 *     "code": number,
 *     "message": "string",
 *      "data" : {
 *          "id": number,
 * }
 */

void auth_register(even_detail *event, http_request_t *request) {
    if (request->body == NULL) {
        sendBadRequest(event, request);
        return;
    }

    cJSON *body = request->body;
    cJSON *username = cJSON_GetObjectItem(body, "username");
    cJSON *password = cJSON_GetObjectItem(body, "password");

    int ret = add_user(username->valuestring, password->valuestring);
    if (ret == -1) {
        sendBadRequest(event, request);
        return;
    }
    cJSON *id_json = cJSON_CreateObject();
    cJSON_AddNumberToObject(id_json, "id", ret);
    cJSON *success_json = http_create_response(RESPONSE_OK, "success", id_json);
    char *message = cJSON_Print(success_json);
    log_debug("%s", message);
    send(event->fd, message, strlen(message), 0);
    free(message);
    cJSON_Delete(success_json);
    return;
}

/**
 * @brief 登录账号
 * request:{
 *     "username": "string",
 *     "password": "string"
 * }
 * response:{
 *     "node": number,
 *     "message": "string",
 *      "data" : {
 *          "id": number,
 * }
 */
void auth_login(even_detail *event, http_request_t *request) {
    if (request->body == NULL) {
        sendBadRequest(event, request);
        return;
    }

    cJSON *body = request->body;
    cJSON *username = cJSON_GetObjectItem(body, "username");
    cJSON *password = cJSON_GetObjectItem(body, "password");

    user_info *user = verify_user(username->valuestring, password->valuestring);

    if (user == NULL) {
        sendBadRequest(event, request);
        return;
    }

    // 登录成功
    cJSON *id_json = cJSON_CreateObject();
    cJSON_AddNumberToObject(id_json, "id", user->id);
    cJSON *success_json = http_create_response(RESPONSE_OK, "success", id_json);
    char *message = cJSON_Print(success_json);
    send(event->fd, message, strlen(message), 0);
    free(message);
    cJSON_Delete(success_json);
    return;
}